﻿using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;

namespace Devonline.AspNetCore;

/// <summary>
/// Represents a business logic layer for managing personal business entities within a specified database context.
/// </summary>
/// <remarks>This class provides functionality for interacting with personal business entities, including data
/// access, caching, and HTTP context integration. It extends <see cref="PersonalBusiness{TDbContext, TPersonalBusiness,
/// string}"/> and implements <see cref="IDataService{TDbContext, TPersonalBusiness, string}"/>.</remarks>
/// <typeparam name="TDbContext">The type of the database context used for data access. Must derive from <see cref="DbContext"/>.</typeparam>
/// <typeparam name="TPersonalBusiness">The type of the personal business entity being managed. Must be a class that implements <see cref="IEntitySet"/> and
/// has a parameterless constructor.</typeparam>
/// <param name="logger"></param>
/// <param name="context"></param>
/// <param name="cache"></param>
/// <param name="httpContextAccessor"></param>
/// <param name="personalService"></param>
/// <param name="httpSetting"></param>
public class PersonalBusiness<TDbContext, TPersonalBusiness>(
    ILogger<PersonalBusiness<TDbContext, TPersonalBusiness>> logger,
    TDbContext context,
    IDistributedCache cache,
    IHttpContextAccessor httpContextAccessor,
    PersonalService<TDbContext> personalService,
    HttpSetting httpSetting) :
    PersonalBusiness<TDbContext, TPersonalBusiness, string>(logger, context, cache, httpContextAccessor, httpSetting),
    IDataService<TDbContext, TPersonalBusiness, string>
    where TDbContext : DbContext
    where TPersonalBusiness : class, IPersonalBusiness, IBusiness, IEntitySet, new()
{
    protected readonly PersonalService<TDbContext> _personalService = personalService;

    /// <summary>
    /// 重载的获取方法内部过滤当前人员的
    /// </summary>
    /// <returns></returns>
    public virtual async Task<IQueryable<TPersonalBusiness>> GetQueryableAsync()
    {
        var personal = await _personalService.GetAsync();
        var queryable = base.GetQueryable(x => x.PersonalId == personal.Id);
        string? businessType = _request.GetFromRequest<string>(nameof(businessType));
        if (!string.IsNullOrWhiteSpace(businessType))
        {
            queryable = queryable.Where(x => x.BusinessType == businessType);
        }

        return queryable;
    }

    /// <summary>
    /// 重载内部添加方法, 自动设置 personalId 属性
    /// </summary>
    /// <param name="entitySet"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    protected override async Task InternalAddAsync(TPersonalBusiness entitySet, DataServiceContext? context = null)
    {
        var personal = await _personalService.GetAsync();
        entitySet.PersonalId = personal.Id;
        await base.InternalAddAsync(entitySet, context);
    }
    /// <summary>
    /// 重载内部更新方法, 自动设置 personalId 属性
    /// </summary>
    /// <param name="entitySet"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    protected override async Task InternalUpdateAsync(TPersonalBusiness entitySet, DataServiceContext? context = null)
    {
        var personal = await _personalService.GetAsync();
        entitySet.PersonalId = personal.Id;
        await base.InternalUpdateAsync(entitySet, context);
    }
}

/// <summary>
/// Provides business logic and data service operations for managing entities of type <typeparamref name="TPersonalBusiness"/>
/// within the specified database context <typeparamref name="TDbContext"/>.
/// </summary>
/// <remarks>This class extends <see cref="DataService{TDbContext, TEntitySet, TKey}"/> and implements <see
/// cref="IDataService{TDbContext, TEntitySet, TKey}"/> to provide additional functionality for handling entity sets. It
/// integrates logging, distributed caching, HTTP context access, and HTTP settings to support advanced business
/// operations.</remarks>
/// <typeparam name="TDbContext">The type of the database context used for data access. Must derive from <see cref="DbContext"/>.</typeparam>
/// <typeparam name="TPersonalBusiness">The type of the entity set managed by this service. Must implement <see cref="IEntitySet{TKey}"/> and have a
/// parameterless constructor.</typeparam>
/// <typeparam name="TKey">The type of the key used to identify entities in the entity set. Must implement <see cref="IConvertible"/>.</typeparam>
/// <param name="logger"></param>
/// <param name="context"></param>
/// <param name="cache"></param>
/// <param name="httpContextAccessor"></param>
/// <param name="httpSetting"></param>
public class PersonalBusiness<TDbContext, TPersonalBusiness, TKey>(
    ILogger<PersonalBusiness<TDbContext, TPersonalBusiness, TKey>> logger,
    TDbContext context,
    IDistributedCache cache,
    IHttpContextAccessor httpContextAccessor,
    HttpSetting httpSetting) :
    DataService<TDbContext, TPersonalBusiness, TKey>(logger, context, cache, httpContextAccessor, httpSetting),
    IDataService<TDbContext, TPersonalBusiness, TKey>
    where TDbContext : DbContext
    where TPersonalBusiness : class, IPersonalBusiness<TKey>, IBusiness<TKey>, IEntitySet<TKey>, new()
    where TKey : IConvertible;